2020-2021 Sunseeker Telemetry and Lighting System
eusci_b_i2c_ex2_masterRXMultiple.c
Go to the documentation of this file.
1 /* --COPYRIGHT--,BSD
2  * Copyright (c) 2017, Texas Instruments Incorporated
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *
12  * * Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  *
16  * * Neither the name of Texas Instruments Incorporated nor the names of
17  * its contributors may be used to endorse or promote products derived
18  * from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  * --/COPYRIGHT--*/
32 /*******************************************************************************
33  * MSP430i2xx EUSCI_B I2C - Master receive multiple bytes
34  *
35  * Description: In this example, the device is configured as an I2C master.
36  * When the slave has data available it pulls the IRQ line (P1.0) down to
37  * tell the master data is ready. The master interrupts on the GPIO transition
38  * and starts an I2C read. The first byte of the slave's packet is the length
39  * of the packet, including the length byte. The master then continues to
40  * read bytes until all data from the packet has been consumed. All data
41  * processing is done in the interrupt service routines and the device stays
42  * in LPM0. Run this example before starting the corresponding slave example.
43  *
44  *
45  * /|\ /|\
46  * MSP430i2041 10k 10k MSP430i2041
47  * slave | | master
48  * ----------------- | | -----------------
49  * | P1.6/UCB0SCL|<-|----+->|P1.6/UCB0SCL |
50  * | | | | |
51  * | | | | |
52  * | P1.7/UCB0SDA|<-+------>|P1.7/UCB0SDA |
53  * | | | |
54  * | P1.0|--------->|P1.0 |
55  * | | | |
56  *
57  * Author: Zack Lalanne
58  ******************************************************************************/
59 
60 #include "driverlib.h"
61 
62 #define SLAVE_ADDRESS 0x48
63 
64 static uint8_t RXData[4];
65 static uint16_t RXDataIndex = 0;
66 static uint16_t NumOfRXBytes;
67 
68 int main(void)
69 {
70  EUSCI_B_I2C_initMasterParam i2cConfig =
71  {
72  EUSCI_B_I2C_CLOCKSOURCE_SMCLK, // SMCLK Clock Source
73  4096000, // SMCLK = 4.096MHz
74  EUSCI_B_I2C_SET_DATA_RATE_400KBPS, // Desired I2C Clock of 400kHz
75  0, // No byte counter threshold
76  EUSCI_B_I2C_NO_AUTO_STOP // No Autostop
77  };
78 
79  WDT_hold(WDT_BASE);
80 
81  // Setting the DCO to use the internal resistor. DCO will be at 16.384MHz
82  CS_setupDCO(CS_INTERNAL_RESISTOR);
83 
84  // Setting SMCLK = DC0 / 4 = 4.096 MHz
85  CS_initClockSignal(CS_SMCLK, CS_CLOCK_DIVIDER_4);
86 
87  // Setting P1.6 and P1.7 as I2C pins
88  GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1,
89  GPIO_PIN6 | GPIO_PIN7,
90  GPIO_PRIMARY_MODULE_FUNCTION);
91 
92  // Using P1.0 as slave interrupt pin
93  GPIO_setAsInputPin(GPIO_PORT_P1, GPIO_PIN0);
94  GPIO_selectInterruptEdge(GPIO_PORT_P1, GPIO_PIN0,
95  GPIO_HIGH_TO_LOW_TRANSITION);
96  GPIO_clearInterrupt(GPIO_PORT_P1, GPIO_PIN0);
97  GPIO_enableInterrupt(GPIO_PORT_P1, GPIO_PIN0);
98 
99  // Setting up I2C communication at 400kHz using SMCLK
100  EUSCI_B_I2C_initMaster(EUSCI_B0_BASE, &i2cConfig);
101 
102  // Set master in transmit mode
103  EUSCI_B_I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_MODE);
104 
105  // Settings slave address
106  EUSCI_B_I2C_setSlaveAddress(EUSCI_B0_BASE, SLAVE_ADDRESS);
107 
108  // Enable the module for operation
109  EUSCI_B_I2C_enable(EUSCI_B0_BASE);
110 
111  // Clear needed I2C interrupts
112  EUSCI_B_I2C_clearInterrupt(EUSCI_B0_BASE,
113  EUSCI_B_I2C_RECEIVE_INTERRUPT0);
114 
115  // Go to sleep and wait for LPM exit
116  __bis_SR_register(LPM0_bits | GIE);
117 }
118 
119 #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
120 #pragma vector=USCI_B0_VECTOR
121 __interrupt
122 #elif defined(__GNUC__)
123 __attribute__((interrupt(USCI_B0_VECTOR)))
124 #endif
125 void USCIB0_ISR(void)
126 {
127  switch(__even_in_range(UCB0IV, USCI_I2C_UCBIT9IFG))
128  {
129  case USCI_NONE: break;
130  case USCI_I2C_UCALIFG: break;
131  case USCI_I2C_UCNACKIFG: break;
132  case USCI_I2C_UCSTTIFG: break;
133  case USCI_I2C_UCSTPIFG: break;
134  case USCI_I2C_UCRXIFG3: break;
135  case USCI_I2C_UCTXIFG3: break;
136  case USCI_I2C_UCRXIFG2: break;
137  case USCI_I2C_UCTXIFG2: break;
138  case USCI_I2C_UCRXIFG1: break;
139  case USCI_I2C_UCTXIFG1: break;
140  case USCI_I2C_UCRXIFG0:
141 
142  // Send stop if second to last byte
143  if(RXDataIndex == NumOfRXBytes - 2)
144  {
145  EUSCI_B_I2C_masterReceiveMultiByteStop(EUSCI_B0_BASE);
146  }
147 
148  RXData[RXDataIndex++] = EUSCI_B_I2C_masterReceiveMultiByteNext(EUSCI_B0_BASE);
149 
150  if(RXDataIndex == 1)
151  {
152  // Save length of packet if first byte
153  NumOfRXBytes = RXData[0];
154  }
155  else if(RXDataIndex == NumOfRXBytes)
156  {
157  // Stop receiving data if last byte
158  EUSCI_B_I2C_disableInterrupt(EUSCI_B0_BASE,
159  EUSCI_B_I2C_RECEIVE_INTERRUPT0);
160  GPIO_enableInterrupt(GPIO_PORT_P1, GPIO_PIN0);
161  RXDataIndex = 0;
162  NumOfRXBytes = 0;
163  }
164  break;
165  case USCI_I2C_UCTXIFG0: break;
166  case USCI_I2C_UCBCNTIFG: break;
167  case USCI_I2C_UCCLTOIFG: break;
168  case USCI_I2C_UCBIT9IFG: break;
169  default: break;
170  }
171 }
172 
173 #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
174 #pragma vector=PORT1_VECTOR
175 __interrupt
176 #elif defined(__GNUC__)
177 __attribute__((interrupt(PORT1_VECTOR)))
178 #endif
179 void PORT1_ISR(void)
180 {
181  switch(__even_in_range(P1IV, 0x10))
182  {
183  case 0x00: break; // No interrupt
184  case 0x02: // P1.0 interrupt
185  // Initiate an I2C read
186  EUSCI_B_I2C_masterReceiveStart(EUSCI_B0_BASE);
187  EUSCI_B_I2C_enableInterrupt(EUSCI_B0_BASE,
188  EUSCI_B_I2C_RECEIVE_INTERRUPT0);
189  GPIO_disableInterrupt(GPIO_PORT_P1, GPIO_PIN0);
190  break;
191  case 0x04: break; // P1.1 interrupt
192  case 0x06: break; // P1.2 interrupt
193  case 0x08: break; // P1.3 interrupt
194  case 0x0A: break; // P1.4 interrupt
195  case 0x0C: break; // P1.5 interrupt
196  case 0x0E: break; // P1.6 interrupt
197  case 0x10: break; // P1.7 interrupt
198  }
199 }
200 
uint8_t RXData
void PORT1_ISR(void)
void USCIB0_ISR(void)